package com.sx.pipeline.ui.map

import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.widget.LinearLayout
import androidx.appcompat.widget.SearchView
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.maps.AMap
import com.amap.api.maps.AMapUtils
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.LocationSource
import com.amap.api.maps.model.*
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.core.PoiItem
import com.amap.api.services.geocoder.*
import com.amap.api.services.poisearch.PoiResult
import com.amap.api.services.poisearch.PoiSearch
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.ToastUtils
import com.hjq.bar.TitleBar
import com.sx.mvvmlibs.bus.RxBus
import com.sx.mvvmlibs.utils.Logs
import com.sx.pipeline.BR
import com.sx.pipeline.R
import com.sx.pipeline.app.base.CYBaseAppBarActivity
import com.sx.pipeline.app.event.BusEvent
import com.sx.pipeline.app.event.EventTypes
import com.sx.pipeline.app.model.CYBaseViewModel
import com.sx.pipeline.arouth.RoutePath
import com.sx.pipeline.databinding.ActSearch2LocationBinding


/**
 * @Author: YY
 * @Date: 2022/8/12
 * @Desc: TODO
 */
@Route(path = RoutePath.Main.SEARCH_LOCATION)
class Search2LocationActivity : CYBaseAppBarActivity<ActSearch2LocationBinding, CYBaseViewModel>(
    R.layout.act_search2_location), View.OnClickListener, SearchView.OnQueryTextListener, LocationSource,
    AMap.OnMapClickListener, AMap.OnMapTouchListener, AMapLocationListener, AMap.OnCameraChangeListener, PoiSearch.OnPoiSearchListener {

    // 选择的位置
    private var poiItem: PoiItem? = null
    // 地图
    private lateinit var aMap: AMap
    // 定位
    private var mLocationListener: LocationSource.OnLocationChangedListener? = null
    private var mLocationClient: AMapLocationClient? = null
    private var mLocationOption: AMapLocationClientOption? = null

    private lateinit var poisList: MutableList<PoiItem>
    private lateinit var geocodeAdapter: GeocodeAdapter

    private var mLocation: AMapLocation? = null
    private var mLatLng: LatLng? = null
    private var getZoomB: Float? = 16f
    private var point: LatLng? = null
    private var marker: Marker? = null
    private var isSelected: Boolean = false
    private var  addressData: RegeocodeAddress?=null;
    private var province=""
    private var city=""
    private var district=""


    override fun initAppBar() {
        getTitleBar().title = "选择地点"
        getTitleBar().setRightTitleColor(Color.parseColor("#333333"))
        getTitleBar().rightTitle = getString(R.string.txt_confirm)
    }

    override fun onRightClick(titleBar: TitleBar?) {
        if (poiItem != null) {
            poiItem?.provinceName=province;
            poiItem?.cityName=city;
            poiItem?.adName=district;
            RxBus.getDefault().post(BusEvent(EventTypes.SELECT_SITE.code, poiItem))
            finish()
        } else {
            ToastUtils.showShort("请选择地点")
        }
    }

    override fun initListener() {
        KeyboardUtils.registerSoftInputChangedListener(this) {
            Logs.d("registerSoftInputChangedListener $it")
            if (it > 0) {
                // 软件盘弹出
                keyBoardShowStatus()
            }
        }
    }

    override fun onClick(v: View?) {
        when(v!!.id) {
            R.id.tv_cancel -> {
                keyBoardHiddenStatus()
            }
            R.id.image_down -> {
                keyBoardHiddenStatus()
            }
        }
    }

    override fun onQueryTextSubmit(query: String?): Boolean {
        Logs.d("onQueryTextSubmit $query")
        return false
    }

    override fun onQueryTextChange(newText: String?): Boolean {
        Logs.d("onQueryTextChange $newText")
        // 搜索地址
        searchAddress(newText!!)
        return true
    }


    override fun onMapClick(p0: LatLng?) {
        Logs.d("onMapClick")
        if (KeyboardUtils.isSoftInputVisible(this)) {
            // 软键盘是否可见
            keyBoardHiddenStatus()
        }
    }

    override fun onTouch(p0: MotionEvent?) {
        Logs.d("onTouch")
        isSelected = false
    }

    /****************************** 定位 ***************************/

    override fun activate(onLocationListener: LocationSource.OnLocationChangedListener?) {
        this.mLocationListener = onLocationListener
        Logs.d("activate")
        if (mLocationClient == null) {
            mLocationClient = AMapLocationClient(this)
            mLocationClient!!.setLocationListener(this)

            mLocationOption = AMapLocationClientOption()
            //只定位一次
            mLocationOption!!.isOnceLocation = true
            mLocationOption!!.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
            mLocationClient!!.setLocationOption(mLocationOption)
            mLocationClient!!.startLocation()
        }
    }

    override fun deactivate() {
        mLocationListener = null
        if (mLocationClient != null) {
            mLocationClient!!.stopLocation()
            mLocationClient!!.onDestroy()
        }
        mLocationClient = null
        mLocationOption = null
    }

    /*********************************** 定位改变 ***********************************/

    override fun onLocationChanged(location: AMapLocation?) {
        if (location != null && this.mLocationListener != null) {
            if (location.errorCode == 0) {
                mLocation = location
                mLocationListener!!.onLocationChanged(location)
                val mLatitude: Double = location.latitude
                val mLongitude: Double = location.longitude
                Logs.d("onLocationChanged $mLatitude  === $mLongitude")
                mLatLng = LatLng(mLatitude, mLongitude)
                // 附近地址
                reGeocodeSearch(mLatitude, mLongitude, 1500)
                if (marker == null) {
                    point = LatLng(location.latitude, location.longitude)
                    //地图发生变化之后描绘mark
                    marker = aMap.addMarker(MarkerOptions()
                        .position(point)
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_select_point)))
                }
            } else {
                val errorText = "faild to located" + location.errorCode + ":" + location.errorInfo
                Logs.e(errorText)
            }
        }
    }

    /******************************** 监听地图发生变化之后 ********************************/

    override fun onCameraChange(cameraPosition: CameraPosition?) {
        if (cameraPosition != null) {
            if (getZoomB != cameraPosition.zoom) {
                Logs.d("onCameraChange 缩放了，不作为 ${cameraPosition.zoom}")
                getZoomB = cameraPosition.zoom
            } else {
                Logs.d("onCameraChange 缩放了 ${cameraPosition.zoom}")
                point = LatLng(cameraPosition.target.latitude, cameraPosition.target.longitude)
                marker?.position = point
            }
        }
    }

    override fun onCameraChangeFinish(cameraPosition: CameraPosition?) {
        if (cameraPosition != null) {
            if (getZoomB != cameraPosition.zoom) {
                Logs.d("onCameraChangeFinish 缩放了，不作为 ${cameraPosition.zoom}")
                getZoomB = cameraPosition.zoom
            } else {
                Logs.d("onCameraChangeFinish  ${cameraPosition.zoom}")
                if (isSelected) {
                    return
                }
                // 发生变化时获取到经纬度传递逆地理编码获取周边数据
                reGeocodeSearch(cameraPosition.target.latitude, cameraPosition.target.longitude, 1500)
            }
        }
    }

    override fun onPoiSearched(result: PoiResult?, code: Int) {
        if (code == 1000) {
            if (result != null) {
                if (!result.pois.isNullOrEmpty()) {
                    geocodeAdapter.clickId = - 1
                    poisList.clear()
                    result.pois.forEach {
                        val poisLatLng = LatLng(it.latLonPoint.latitude, it.latLonPoint.longitude)
                        it.distance = AMapUtils.calculateLineDistance(poisLatLng, mLatLng).toInt()
                    }
                    poisList = result.pois
                }
                setAddressList(poisList)
            }
        }
    }

    override fun onPoiItemSearched(p0: PoiItem?, p1: Int) {

    }


    override fun initData(bundle: Bundle?) {
        super.initData()
        mBinding.setVariable(BR.onClick, this)
        mBinding.tvSearch.setIconifiedByDefault(false)
        mBinding.tvSearch.isSubmitButtonEnabled = false
        mBinding.tvSearch.queryHint = "搜索地点"
        mBinding.tvSearch.findViewById<View>(androidx.appcompat.R.id.search_plate).background = null
        mBinding.tvSearch.findViewById<View>(androidx.appcompat.R.id.submit_area).background = null
        mBinding.tvSearch.setOnQueryTextListener(this)

        mBinding.mapView.onCreate(bundle)
        if (!this::aMap.isInitialized) {
            aMap = mBinding.mapView.map
        }
        initMapLocation()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mBinding.mapView.onSaveInstanceState(outState)
    }

    override fun onResume() {
        super.onResume()
        mBinding.mapView.onResume()
    }

    override fun onPause() {
        super.onPause()
        mBinding.mapView.onPause()
    }

    override fun onDestroy() {
        if (mLocationClient != null) {
            mLocationClient!!.stopLocation()
            mLocationClient!!.onDestroy()
        }
        mBinding.mapView.onDestroy()
        // 注销软键盘
        KeyboardUtils.unregisterSoftInputChangedListener(window)
        super.onDestroy()
    }


    /**
     * 初始化地图定位
     */
    private fun initMapLocation() {
        val myLocationStyle = MyLocationStyle()
        // locationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.em_unread_count_bg));
        myLocationStyle.strokeColor(Color.BLACK)
        myLocationStyle.radiusFillColor(Color.argb(100, 0, 0, 180))
        myLocationStyle.strokeWidth(1.0f)
        // 缩放比例
        aMap.moveCamera(CameraUpdateFactory.zoomTo(16f))
        // 设置定位蓝点的Style
        aMap.myLocationStyle = myLocationStyle
        // 地图定位
        aMap.setLocationSource(this)
        // 设置默认定位按钮是否显示
        aMap.uiSettings.isMyLocationButtonEnabled = true
        // 设置缩放按钮是否显示
        aMap.uiSettings.isZoomControlsEnabled = false
        // 设置比例尺控件是否显示
        aMap.uiSettings.isScaleControlsEnabled = false
        // 设置为true表示启动显示定位蓝点，false表示隐藏定位蓝点并不进行定位
        aMap.isMyLocationEnabled = true
        //监听地图发生变化之后
        aMap.setOnCameraChangeListener(this)
        // 触摸事件
        aMap.setOnMapTouchListener(this)
    }

    /**
     * 逆编码获取定位后的附近地址
     * @param latitude
     * @param longitude
     * @param distances 设置查找范围
     */
    private fun reGeocodeSearch(latitude: Double, longitude: Double, distances: Int) {
        val point = LatLonPoint(latitude, longitude)
        val geocodeSearch = GeocodeSearch(this)
        val reGeocodeQuery = RegeocodeQuery(point, distances.toFloat(), GeocodeSearch.AMAP)
        geocodeSearch.getFromLocationAsyn(reGeocodeQuery)

        geocodeSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
            override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult?, rCode: Int) {
                if (1000 == rCode) {
                    if (regeocodeResult != null) {
                        val address: RegeocodeAddress = regeocodeResult.regeocodeAddress
                        addressData=regeocodeResult.regeocodeAddress
                         province = address.province //省或直辖市
                         city = address.city //地级市或直辖市
                         district = address.district //区或县或县级市
                        district = address.businessAreas[0].name

                        Logs.d("addresseee1${mLocation?.latitude} ${mLocation?.longitude}")
                        poisList = address.pois //获取周围兴趣点
                        poisList.forEach {
                            val poisLatLng = LatLng(it.latLonPoint.latitude, it.latLonPoint.longitude)
                            it.distance = AMapUtils.calculateLineDistance(poisLatLng, mLatLng).toInt()
                        }
                        setAddressList(poisList)
                    }
                }
            }

            override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {

            }
        })
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun setAddressList(data: List<PoiItem>) {
        if (data.isNotEmpty()) {
            mBinding.progressBar.visibility = View.GONE
            if (!this::geocodeAdapter.isInitialized) {
                mBinding.recyclerAddress.layoutManager = LinearLayoutManager(this,
                    LinearLayoutManager.VERTICAL, false)
                geocodeAdapter = GeocodeAdapter(data as MutableList<PoiItem>)
                mBinding.recyclerAddress.adapter = geocodeAdapter

                poiItem  = geocodeAdapter.data[0]
                poiItem?.provinceName="广东省"
                poiItem?.cityName="东莞市"
                poiItem?.adName="南城区"
                // 选择事件
                geocodeAdapter.setOnItemClickListener { adapter, view, position ->
                    geocodeAdapter.setSelectClickId(position)

                    poiItem = adapter.data[position] as PoiItem

                    point = LatLng(poiItem!!.latLonPoint.latitude, poiItem!!.latLonPoint.longitude)
                    marker?.position = point

                    // 移动marker
                    aMap.moveCamera(CameraUpdateFactory.newCameraPosition(CameraPosition(point, 16f, 0f, 0f)))

                    isSelected = true
                    province= poiItem?.provinceName.toString()
                    city= poiItem?.cityName.toString()
                    district= poiItem?.adName.toString()
                    Logs.d("addresseeeitem选中${poiItem?.provinceName} == $${poiItem?.cityName} == $${poiItem?.adName}")
                    Logs.d("addresseeeitem选中${poiItem!!.latLonPoint.latitude} ${poiItem!!.latLonPoint.latitude}")
                }

            } else {
                geocodeAdapter.data = data as MutableList<PoiItem>
                geocodeAdapter.notifyDataSetChanged()
                poiItem = geocodeAdapter.data[geocodeAdapter.clickId]
            }
        }
    }

    private fun searchAddress(etText: String) {
        if (mLocation != null) {
            Logs.d("searchAddress ${mLocation!!.latitude} === ${mLocation!!.longitude}")
            val lp = LatLonPoint(mLocation!!.latitude, mLocation!!.longitude)
            val poiQuery = PoiSearch.Query(etText, "", mLocation!!.cityCode)
            poiQuery.pageSize = 25
            poiQuery.pageNum = 1
            //poiQuery.location = lp
            val poiSearch = PoiSearch(this, poiQuery)
            poiSearch.setOnPoiSearchListener(this)
            poiSearch.searchPOIAsyn()
        }
    }

    /**
     * 弹出软件盘 设置列表高度
     */
    private fun keyBoardShowStatus() {
        val layoutParams = mBinding.llLayout.layoutParams as (LinearLayout.LayoutParams)
        layoutParams.weight = 2.2f
        mBinding.llLayout.layoutParams = layoutParams

        mBinding.tvCancel.visibility = View.VISIBLE
        mBinding.imageDown.visibility = View.VISIBLE

    }

    /**
     * 收回软键盘、恢复列表高度
     */
    private fun keyBoardHiddenStatus() {
        // 收回软件盘
        KeyboardUtils.hideSoftInput(window)
        // 收缩布局
        val layoutParams = mBinding.llLayout.layoutParams as (LinearLayout.LayoutParams)
        layoutParams.weight = 0.7f
        mBinding.llLayout.layoutParams = layoutParams

        mBinding.tvCancel.visibility = View.GONE
        mBinding.imageDown.visibility = View.GONE
    }

}